<!--
 * Copyright ©
 * #  
 * @author: zw
 * @date: 2022-01-11 
 -->


<template>
  <div class='playlist'>
    <div class="w1200">
      <div class="filter">
        <div class="filter-item" v-for="(item, index) in categories" :key="index">
          <div class="filter-title">{{ item.name }}</div>
          <div class="filter-box">
            <span :class="['item-box', curType === sub.name ? 'active' : '']" v-for="sub in item.children.slice(0, 8)" :key="sub.name"><em @click="selectType(sub)">{{ sub.name }}</em></span>

            <el-popover :width="'auto'" trigger="click">
              <template #reference>
                <span :class="['item-box', 'filter-more', moreTxt[index] ? 'active' : '']" v-if="item.children.length > 9"><em>{{ moreTxt[index] ? curType : '更多'}}<i class="iconfont icon-arrow"></i></em></span>
                <span v-else></span>
              </template>
              <div class="filter-drop">
                <span :class="['item-box', curType === sub.name ? 'active' : '']" v-for="sub in item.children.slice(9)" :key="sub.name"><em @click="selectType(sub, index)">{{ sub.name }}</em></span>
              </div>
            </el-popover>
          </div>
        </div>
      </div>
      <div class="list-container">
        <div class="list-head">
          <h2>{{curType}} <em v-if="curType !== allList.name" class="filter-close" @click="closed"><i class="iconfont icon-closed"></i></em></h2>
          <div class="type">
            <span :class="params.order === 'hot' ? 'active' : ''" @click="selectOrder('hot')">热门</span>
            <span :class="params.order === 'new' ? 'active' : ''" @click="selectOrder('new')">最新</span>
          </div>
        </div>
        <div class='wrapper infinite-list' v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="100">
          <play-list :playList="playlist_list" :loading="playlist_loading" :num="playlist_count"></play-list>
          <template v-if="busy">
            <Loading />
          </template>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { defineComponent, onMounted, reactive, toRefs, watch } from 'vue';
import { CATLIST, PLAYLIST } from "@/api";
import { useInstance } from "@/hooks";
export default defineComponent({
  name: 'PlayList',
  setup(props, { emit, slots }) {
    const { $router: router, $Message: $message } = useInstance();
    const { info, getCatlist, getPlayList, getMoreTxt } = initCatlistRequest(router, $message);

    const loadMore = () => {
      info.busy = true;
      info.params.offset = info.playlist_list.length;
    };
    const selectType = (item) => {
      router.push({ path: 'playlist', query: { cat: item.name, order: info.params.order } });
    };
    const selectOrder = (type) => {
      router.push({ path: 'playlist', query: { cat: info.params.cat, order: type } });
    };
    const closed = () => {
      router.push({ path: 'playlist' })
    };
    watch(() => router.currentRoute.value.query, (newVal, oldVal) => {
      const { cat, order } = newVal;

      info.curType = cat || info.allList.name
      info.params = Object.assign({}, { order: 'hot', cat: '', limit: 50, offset: 0 }, { cat: cat || '', order: order || 'hot' })
      getMoreTxt()
    });

    watch(() => info.params, (newVal, oldVal) => {
      if (newVal.cat !== oldVal.cat) {
        info.busy = true;
        info.playlist_list = [];
      }
      getPlayList(newVal)
    }, {
      deep: true // 深度监听
    });
    onMounted(() => { getCatlist(); getPlayList(info.params); });
    return {
      ...toRefs(info),
      loadMore,
      selectType,
      selectOrder,
      closed
    }
  }
});
function initCatlistRequest(router, $message) {
  const cat = router.currentRoute.value.query.cat;
  const info = reactive({
    sub: [],
    categories: [],
    curType: '',
    moreTxt: {},
    allList: {},
    playlist_list: [],
    playlist_count: 20,
    playlist_loading: true,
    busy: true,
    params: {
      order: 'hot',
      cat: cat,
      limit: 50,
      offset: 0
    }
  });
  const getCatlist = async () => {
    const { code, sub, categories, all } = await CATLIST({});
    info.sub = sub
    if (code !== 200) return $message.error('数据请求失败');
    for (const k in categories) {
      const params = { name: categories[k] }
      params.children = info.sub.filter(subItem => subItem.category === Number(k));
      info.categories.push(params)
    }

    info.curType = cat ? cat : all.name
    info.allList = all
    getMoreTxt();
  };
  const getPlayList = async (params) => {
    const defaults = { order: 'hot', cat: '', limit: 50, offset: 0 }
    const { code, playlists, total } = await PLAYLIST({ ...defaults, ...params });
    if (code !== 200) return $message.error('数据请求失败')
    info.playlist_list = info.params.offset !== 0 ? [...info.playlist_list, ...playlists] : playlists
    info.busy = info.playlist_list.length >= total;
    info.playlist_loading = false;
  };
  const getMoreTxt = () => {
    // 查询当前显示的歌单分类详情，如：全部歌单、华语
    const itemInfo = info.sub.find(subItem => subItem.name === info.curType)
    info.moreTxt = {}
    if (itemInfo) { // 若有歌单分类，且分类歌单的索引在更多里面，则渲染moreText数据
      const index = info.categories[itemInfo.category].children.indexOf(itemInfo)
      index >= 8 && (info.moreTxt[itemInfo.category] = itemInfo)
    }
  }
  return {
    info,
    getCatlist,
    getPlayList,
    getMoreTxt
  }
}
</script>

<style lang='scss' scoped>
.wrapper {
  min-height: 500px;
}
.filter {
  display: flex;
  padding: 40px 0;
}
.filter-item {
  flex: 2;
  border-left: 1px solid #f5f5f5;
  padding-left: 35px;

  .filter-title {
    font-weight: bold;
    margin-bottom: 5px;
  }

  .filter-box {
    font-size: 0;
  }

  .item-box {
    display: inline-block;
    width: calc(100% / 3);
    vertical-align: top;

    em {
      display: inline-block;
      font-style: normal;
      font-size: 14px;
      line-height: 26px;
      margin-top: 4px;
      cursor: pointer;
    }

    &.active {
      em {
        padding: 0 6px 0 5px;
        margin: 4px -5px 0;
        color: #fff;
        font-style: normal;
        background: $color-theme;
      }
    }
  }

  .filter-more {
    width: 50px;

    &.active {
      em {
        width: 40px;
        overflow: hidden;
        height: 26px;
        text-overflow: ellipsis;
        white-space: nowrap;
        vertical-align: top;
      }
    }
  }

  &:first-child {
    flex: 1;
    border: 0;
    padding-left: 0;

    .item-box {
      width: 50%;
    }
  }
}
.filter-drop {
  .item-box {
    display: inline-block;
    line-height: 26px;
    padding: 0 15px;
    font-size: 14px;

    em {
      display: inline-block;
      font-style: normal;
      cursor: pointer;
    }

    &.active {
      em {
        padding: 0 5px;
        margin: 0 -5px;
        color: #fff;
        font-style: normal;
        background: $color-theme;
      }
    }
  }
}

.list-head {
  display: flex;
  padding: 15px 0;

  h2 {
    font-size: 24px;
    line-height: 30px;
  }

  .filter-close {
    display: inline-block;
    line-height: 16px;
    vertical-align: top;
    cursor: pointer;
  }

  .type {
    flex: 1;
    padding: 5px 40px;

    span {
      position: relative;
      display: inline-block;
      height: 20px;
      line-height: 20px;
      margin-right: 34px;
      font-weight: 300;
      color: #333;
      cursor: pointer;

      &.active {
        font-weight: 600;
        color: #000;

        &::after {
          position: absolute;
          content: "";
          left: 0;
          bottom: 1px;
          width: 100%;
          height: 6px;
          background: $color-theme;
          z-index: -1;
        }
      }
    }
  }
}
</style>
